package org.duoduo.common.redis.jedis3_1_0;

import com.duoduo.common.api.JsonDeserializationException;
import com.duoduo.common.api.constants.Constant;
import com.duoduo.common.api.constants.LogConstant;
import com.duoduo.common.api.help.JsonInnerUtil;
import com.duoduo.common.api.help.ListInnerUtil;
import com.duoduo.common.api.help.SerializationInnerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.params.SetParams;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Map.Entry;

/**
 * 内存数据库REDIS的辅助类,负责对内存数据库的所有操作
 *
 */
public class RedisUtil {
	
	private static Logger logger = LoggerFactory.getLogger(RedisUtil.class);
	private static final String LOCK_SUCCESS = "OK";

	public static Object eval(final String redisKey, final String appName, final String script, final List<String> keys, final List<String> params) {
        return new RedisExecutor<Object>() {
            @Override
            public Object execute(String redisClusterType, Object jedis, String appName) {
            	if(ListInnerUtil.isNotEmpty(keys)){
            		List<String> newkeys = new ArrayList<>(keys.size());
            		for (String key : keys) {
            			newkeys.add(appName + key);
					}
            		if(redisClusterType.equals("cluster")){
            			return ((JedisCluster)jedis).eval(script, newkeys, params);
            		}else{
            			return ((Jedis)jedis).eval(script, newkeys, params);
            		}
            	}else{
            		return null;
            	}
            }
        }.getResult(redisKey, appName);
    }

	public static Object evalByte(final String redisKey, final String appName, final String script, final List<String> keys, final List<byte[]> params){
		return new RedisExecutor<Object>() {
            @Override
            public Object execute(String redisClusterType, Object jedis, String appName) {
            	try{
	            	if(ListInnerUtil.isNotEmpty(keys)){
	            		List<byte[]> newkeys = new ArrayList<>(keys.size());
	            		for (String key : keys) {
	            			newkeys.add((appName + key).getBytes(Constant.CHARSET));
						}
	            		if(redisClusterType.equals("cluster")){
	            			return ((JedisCluster)jedis).eval(script.getBytes(Constant.CHARSET), newkeys, params);
	            		}else{
	            			return ((Jedis)jedis).eval(script.getBytes(Constant.CHARSET), newkeys, params);
	            		}
	            	}else{
	            		return null;
	            	}
            	} catch (UnsupportedEncodingException e) {
            		logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
            }
        }.getResult(redisKey, appName);
	}

	//==============================================================

    /**
     * 删除单个key
     *
     * @param key key
     * @return 删除成功的条数
     */
    public static Long delKey(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).del(appName + key);
            	}else{
            		return ((Jedis)jedis).del(appName + key);
            	}
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 删除多个key
     *
     * @param keys 匹配的key的集合
     * @return 删除成功的条数
     */
    public static Long delKeys(final String redisKey, final String appName, final String[] keys) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	//拼前缀
            	for (int i = 0; i < keys.length; i++) {
            		keys[i] = appName + keys[i];
            	}
            	if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).del(keys);
            	}else{
            		return ((Jedis)jedis).del(keys);
            	}
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 获取给定 key的有效期.
     *
     * @param appName 应用前缀
     * @param key key
     * @return 过期时间（秒）
     */
    public static Long ttl(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
        		return ((Jedis)jedis).ttl(appName + key);
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 为给定 key设置有效期.
     *
     * @param key key
     * @param expire 有效期（秒）
     * @return 1:设置成功,0:已经超时或key不存在
     */
    public static Long expire(final String redisKey, final String appName, final String key, final int expire) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).expire(appName + key, expire);
            	}else{
            		return ((Jedis)jedis).expire(appName + key, expire);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static Long expireByteArr(final String redisKey, final String appName, final String key, final int expire) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			try{
    				if(redisClusterType.equals("cluster")){
    	            	return ((JedisCluster)jedis).expire((appName + key).getBytes(Constant.CHARSET), expire);
                	}else{
                		return ((Jedis)jedis).expire((appName + key).getBytes(Constant.CHARSET), expire);
                	}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }
    
    /**
     * 判断key是否存在
     *
     * @param key key
     * @return true存在，false不存在
     */
    public static Boolean exists(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Boolean>() {
            @Override
            public Boolean execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).exists(appName + key);
            	}else{
            		return ((Jedis)jedis).exists(appName + key);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static Boolean existsSeri(final String redisKey, final String appName, final String key) {
    	return new RedisExecutor<Boolean>() {
    		@Override
    		public Boolean execute(String redisClusterType, Object jedis, String appName) {
    			try {
	    			if(redisClusterType.equals("cluster")){
	    				return ((JedisCluster)jedis).exists((appName + key).getBytes(Constant.CHARSET));
	    			}else{
	    				return ((Jedis)jedis).exists((appName + key).getBytes(Constant.CHARSET));
	    			}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return false;
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**对存储的key的数值执行原子（跨JVM）的加1操作
     *
     * @param key key
     * @return 执行递增操作后key对应的值
     */
	public static long incr(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
	                long id = ((JedisCluster)jedis).incr(appName + key);
	                if ((id + 75807) >= Long.MAX_VALUE) {
	                    // 避免溢出,重置,set命令之前允许incr插队,75807就是预留的插队空间
	                    ((Jedis)jedis).set(appName + key, "0");
	                }
	                return id;
            	}else{
            		long id = ((Jedis)jedis).incr(appName + key);
	                if ((id + 75807) >= Long.MAX_VALUE) {
	                    // 避免溢出,重置,set命令之前允许incr插队,75807就是预留的插队空间
	                    ((Jedis)jedis).set(appName + key, "0");
	                }
	                return id;
            	}
            }
        }.getResult(redisKey, appName);
    }
    
	/**对存储的key的数值执行原子（跨JVM）的减1操作
     *
     * @param key key
     * @return 执行递减操作后key对应的值
     */
	public static long decr(final String redisKey, final String appName, final String key) {
		return new RedisExecutor<Long>() {
			@Override
			public Long execute(String redisClusterType, Object jedis, String appName) {
				if(redisClusterType.equals("cluster")){
					return ((JedisCluster)jedis).decr(appName + key);
				}else{
					return ((Jedis)jedis).decr(appName + key);
				}
			}
		}.getResult(redisKey, appName);
	}

    /* ================================Strings================================ */

    /**在使用setNx同时设置过期时间
     * @param appName
     * @param key
     * @param value
     * @param expireMsTime 有效期（毫秒）
     * @return
     */
    public static Boolean setNxPx(final String redisKey, final String appName, final String key, final String value, final long expireMsTime) {
        return new RedisExecutor<Boolean>() {
            @Override
            public Boolean execute(String redisClusterType, Object jedis, String appName) {
            	String result = null;
            	SetParams params = new SetParams();
            	params.nx();
            	params.px(expireMsTime);
            	if(redisClusterType.equals("cluster")){
            		result = ((JedisCluster)jedis).set(appName + key, value, params);
            	}else{
            		result = ((Jedis)jedis).set(appName + key, value, params);
            	}
            	if (LOCK_SUCCESS.equals(result)) {
                    return true;
                }
            	return false;
            }
        }.getResult(redisKey, appName);
    }
    /**在使用setNx同时设置过期时间
     * @param appName
     * @param key
     * @param value
     * @param expireSTime 有效期（秒）
     * @return
     */
    public static Boolean setNxEx(final String redisKey, final String appName, final String key, final String value, final long expireSTime) {
    	return new RedisExecutor<Boolean>() {
    		@Override
    		public Boolean execute(String redisClusterType, Object jedis, String appName) {
    			String result = null;
    			SetParams params = new SetParams();
    			params.nx();
            	params.ex((int)expireSTime);
    			if(redisClusterType.equals("cluster")){
    				result = ((JedisCluster)jedis).set(appName + key, value, params);
    			}else{
    				result = ((Jedis)jedis).set(appName + key, value, params);
    			}
    			if (LOCK_SUCCESS.equals(result)) {
    				return true;
    			}
    			return false;
    		}
    	}.getResult(redisKey, appName);
    }
    /**在使用setNx同时设置过期时间
     * @param appName
     * @param key
     * @param value
     * @param expireMsTime 有效期（毫秒）
     * @return
     */
    public static <T extends Serializable> Boolean setNxPxImplSeri(final String redisKey, final String appName, final String key, final T value, final long expireMsTime) {
    	return new RedisExecutor<Boolean>() {
    		@Override
    		public Boolean execute(String redisClusterType, Object jedis, String appName) {
    			try{
	    			String result = null;
	    			SetParams params = new SetParams();
	    			params.nx();
	            	params.px(expireMsTime);
	    			if(redisClusterType.equals("cluster")){
	    				result = ((JedisCluster)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value), params);
	    			}else{
	    				result = ((Jedis)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value), params);
	    			}
	    			if (LOCK_SUCCESS.equals(result)) {
	    				return true;
	    			}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return false;
				}
    			return false;
    		}
    	}.getResult(redisKey, appName);
    }
    /**在使用setNx同时设置过期时间
     * @param appName
     * @param key
     * @param value
     * @param expireSTime 有效期（秒）
     * @return
     */
    public static <T extends Serializable> Boolean setNxExImplSeri(final String redisKey, final String appName, final String key, final T value, final long expireSTime) {
    	return new RedisExecutor<Boolean>() {
    		@Override
    		public Boolean execute(String redisClusterType, Object jedis, String appName) {
    			try{
    				String result = null;
    				SetParams params = new SetParams();
        			params.nx();
                	params.ex((int)expireSTime);
    				if(redisClusterType.equals("cluster")){
    					result = ((JedisCluster)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value), params);
    				}else{
    					result = ((Jedis)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value), params);
    				}
    				if (LOCK_SUCCESS.equals(result)) {
    					return true;
    				}
    			} catch (UnsupportedEncodingException e) {
    				logger.error(LogConstant.REDIS_CACHE, e);
    				return false;
    			}
    			return false;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 将键key设定为指定的value值 . <br>
     * 如果 key已经持有其他值, 将覆写旧值,无视类型. <br>
     * 对于某个原本带有生存时间（TTL）的键来说,将会清除原有的 TTL.<br>
     * 时间复杂度：O(1)
     *
     * @param key key
     * @param value value
     * @return 在操作成功完成时返回 OK
     */
    public static String set(final String redisKey, final String appName, final String key, final String value) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).set(appName + key, value);
            	}else{
            		return ((Jedis)jedis).set(appName + key, value);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> String set(final String redisKey, final String appName, final String key, final T value) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			if(redisClusterType.equals("cluster")){
    				return ((JedisCluster)jedis).set(appName + key, JsonInnerUtil.objecttoJSon(value));
    			}else{
    				return ((Jedis)jedis).set(appName + key, JsonInnerUtil.objecttoJSon(value));
    			}
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> String setImplSeri(final String redisKey, final String appName, final String key, final T value) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			try{
	    			if(redisClusterType.equals("cluster")){
		            	return ((JedisCluster)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}else{
	            		return ((Jedis)jedis).set((appName + key).getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return "";
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 将键key设定为指定的value值 ,并将 key的生存时间设为 expire（以秒为单位）.<br>
     * 如果 key 已经存在, 将覆写旧值. <br>
     * 时间复杂度：O(1)
     *
     * @param key key
     * @param value value
     * @param expire 有效期（秒）
     * @return 在操作成功完成时返回 OK.当 expire参数不合法时,返回一个错误.
     */
    public static String set(final String redisKey, final String appName, final String key, final String value, final int expire) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).setex(appName + key, expire, value);
            	}else{
            		return ((Jedis)jedis).setex(appName + key, expire, value);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> String set(final String redisKey, final String appName, final String key, final T value, final int expire) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			if(redisClusterType.equals("cluster")){
    				return ((JedisCluster)jedis).setex(appName + key, expire, JsonInnerUtil.objecttoJSon(value));
    			}else{
    				return ((Jedis)jedis).setex(appName + key, expire, JsonInnerUtil.objecttoJSon(value));
    			}
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> String setImplSeri(final String redisKey, final String appName, final String key, final T value, final int expire) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			try{
	    			if(redisClusterType.equals("cluster")){
		            	return ((JedisCluster)jedis).setex((appName + key).getBytes(Constant.CHARSET), expire, SerializationInnerUtil.encode(value));
	            	}else{
	            		return ((Jedis)jedis).setex((appName + key).getBytes(Constant.CHARSET), expire, SerializationInnerUtil.encode(value));
	            	}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return "";
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 将键key设定为指定的value值 ,只有key不存在的时候才会设置key的值. <br>
     * 时间复杂度：O(1)
     *
     * @param key key
     * @param value value
     * @return 设置成功返回 1,设置失败返回 0
     */
    public static Long setIfNotExists(final String redisKey, final String appName, final String key, final String value) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).setnx(appName + key, value);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Long setIfNotExists(final String redisKey, final String appName, final String key, final T value) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			return ((Jedis)jedis).setnx(appName + key, JsonInnerUtil.objecttoJSon(value));
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回key的value<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @return 当 key不存在时,返回 nil,否则返回 key 的值.如果 key的value不是string,就返回一个错误.
     */
    public static String get(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).get(appName + key);
            	}else{
            		return ((Jedis)jedis).get(appName + key);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> T get(final String redisKey, final String appName, final String key, final Class<T> clazz) {
    	return new RedisExecutor<T>() {
    		@Override
    		public T execute(String redisClusterType, Object jedis, String appName) {
    			T result = null;
    			try {
					result = JsonInnerUtil.jsonToObject(((Jedis)jedis).get(appName + key), clazz);
				} catch (JsonDeserializationException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
				}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> T getObjImplSeri(final String redisKey, final String appName, final String key, final Class<T> clazz) {
    	return new RedisExecutor<T>() {
    		@Override
    		public T execute(String redisClusterType, Object jedis, String appName) {
    			try{
	    			if(redisClusterType.equals("cluster")){
		            	return SerializationInnerUtil.decode(((JedisCluster)jedis).get((appName + key).getBytes(Constant.CHARSET)), clazz);
	            	}else{
	            		return SerializationInnerUtil.decode(((Jedis)jedis).get((appName + key).getBytes(Constant.CHARSET)), clazz);
	            	}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量 {@link #set(String, String)}
     *
     * @param pairs 键值对数组{数组第一个元素为key,第二个元素为value}
     * @return 操作状态的集合
     */
    public static List<String> batchSet(final String redisKey, final String appName, final List<Pair<String, String>> pairs) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(pairs == null || pairs.size() == 0){
            		return new ArrayList<String>(0);
            	}
            	List<String> result = new ArrayList<String>(pairs.size());
                for (Pair<String, String> pair : pairs) {
                	result.add(((Jedis)jedis).set(appName + pair.getKey(), pair.getValue()));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<String> batchSetT(final String redisKey, final String appName, final List<Pair<String, T>> pairs) {
    	return new RedisExecutor<List<String>>() {
    		@Override
    		public List<String> execute(String redisClusterType, Object jedis, String appName) {
    			if(pairs == null || pairs.size() == 0){
            		return new ArrayList<String>(0);
            	}
    			List<String> result = new ArrayList<String>(pairs.size());
    			for (Pair<String, T> pair : pairs) {
    				result.add(((Jedis)jedis).set(appName + pair.getKey(), JsonInnerUtil.objecttoJSon(pair.getValue())));
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量 {@link #get(String)}
     *
     * @param keys key数组
     * @return value的集合
     */
    public static List<String> mget(final String redisKey, final String appName, final String[] keys) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(keys == null || keys.length == 0){
            		return new ArrayList<String>(0);
            	}
                String[] newKeys = Arrays.stream(keys).map(name -> appName + name).toArray(String[]::new);
                if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).mget(newKeys);
            	}else{
            		return ((Jedis)jedis).mget(newKeys);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<T> mget(final String redisKey, final String appName, final String[] keys, final Class<T> clazz) {
    	return new RedisExecutor<List<T>>() {
    		@Override
    		public List<T> execute(String redisClusterType, Object jedis, String appName) {
    			if(keys == null || keys.length == 0){
            		return new ArrayList<T>(0);
            	}
    			String[] newKeys = Arrays.stream(keys).map(name -> appName + name).toArray(String[]::new);
                List<String> result = new ArrayList<>(keys.length);
                if(redisClusterType.equals("cluster")){
                	result = ((JedisCluster)jedis).mget(newKeys);
            	}else{
            		result = ((Jedis)jedis).mget(newKeys);
            	}
    			return ListInnerUtil.kListToTList(result, value -> {
    				try {
    					return JsonInnerUtil.jsonToObject(value, clazz);
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
						return null;
					}
    			});
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T> Map<String, T> batchGetReturnMap(final String redisKey, final String appName, final String[] keys, final Class<T> clazz) {
    	return new RedisExecutor<Map<String, T>>() {
    		@Override
    		public Map<String, T> execute(String redisClusterType, Object jedis, String appName) {
    			if(keys == null || keys.length == 0){
    				return new HashMap<String, T>(0);
    			}
    			Map<String, T> result = new HashMap<String, T>(keys.length);
    			for (String key : keys) {
    				try {
						result.put(key, JsonInnerUtil.jsonToObject(((Jedis)jedis).get(appName + key), clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /* ================================Hashes================================ */

    /**
     * 将哈希表 key中的域field的值设为 value.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1. 如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.
     */
    public static Long hashSet(final String redisKey, final String appName, final String key, final String field, final String value) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).hset(appName + key, field, value);
            	}else{
            		return ((Jedis)jedis).hset(appName + key, field, value);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Long hashSet(final String redisKey, final String appName, final String key, final String field, final T value) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			if(redisClusterType.equals("cluster")){
    				return ((JedisCluster)jedis).hset(appName + key, field, JsonInnerUtil.objecttoJSon(value));
    			}else{
    				return ((Jedis)jedis).hset(appName + key, field, JsonInnerUtil.objecttoJSon(value));
    			}
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> Long hashSetImplSeri(final String redisKey, final String appName, final String key, final String field, final T value) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			try{
	    			if(redisClusterType.equals("cluster")){
		            	return ((JedisCluster)jedis).hset((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}else{
	            		return ((Jedis)jedis).hset((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 将哈希表 key中的域field的值设为 value,同时设置哈希表key的有效期.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @param expire 有效期（秒）
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1.如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.异常返回null
     */
    public static Long hashSet(final String redisKey, final String appName, final String key, final String field, final String value, final int expire) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	Long result = null;
            	if(redisClusterType.equals("cluster")){
	            	result = ((JedisCluster)jedis).hset(appName + key, field, value);
            	}else{
            		result = ((Jedis)jedis).hset(appName + key, field, value);
            	}
            	expire(redisKey, appName, key, expire);
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Long hashSet(final String redisKey, final String appName, final String key, final String field, final T value, final int expire) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			Long result = null;
            	if(redisClusterType.equals("cluster")){
            		result = ((JedisCluster)jedis).hset(appName + key, field, JsonInnerUtil.objecttoJSon(value));
            	}else{
            		result = ((Jedis)jedis).hset(appName + key, field, JsonInnerUtil.objecttoJSon(value));
            	}
    			expire(redisKey, appName, key, expire);
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T> Long hashSet(final String redisKey, final String appName, final String key, final byte[] field, final byte[] value, final int expire) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			try{
    				Long result = null;
    				if(redisClusterType.equals("cluster")){
    					result = ((JedisCluster)jedis).hset((appName + key).getBytes(Constant.CHARSET), field, value);
                	}else{
                		result = ((Jedis)jedis).hset((appName + key).getBytes(Constant.CHARSET), field, value);
                	}
	    			expireByteArr(redisKey, appName, key, expire);
	    			return result;
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> Long hashSetImplSeri(final String redisKey, final String appName, final String key, final String field, final T value, final int expire) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			try{
    				Long result = null;
	    			if(redisClusterType.equals("cluster")){
	    				result = ((JedisCluster)jedis).hset((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}else{
	            		result = ((Jedis)jedis).hset((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET), SerializationInnerUtil.encode(value));
	            	}
	    			expireByteArr(redisKey, appName, key, expire);
	    			return result;
    			} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表key中给定域 field的值.<br>
     * 时间复杂度:O(1)
     *
     * @param key key
     * @param field 域
     * @return 给定域的值.当给定域不存在或是给定 key不存在时,返回 nil .
     */
    public static String hashGet(final String redisKey, final String appName, final String key, final String field) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).hget(appName + key, field);
            	}else{
            		return ((Jedis)jedis).hget(appName + key, field);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> T hashGet(final String redisKey, final String appName, final String key, final String field, final Class<T> clazz) {
    	return new RedisExecutor<T>() {
    		@Override
    		public T execute(String redisClusterType, Object jedis, String appName) {
    			T result = null;
    			try {
    				if(redisClusterType.equals("cluster")){
    					result = JsonInnerUtil.jsonToObject(((JedisCluster)jedis).hget(appName + key, field), clazz);
    				}else{
    					result = JsonInnerUtil.jsonToObject(((Jedis)jedis).hget(appName + key, field), clazz);
    				}
				} catch (JsonDeserializationException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
				}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> T hashGetImplSeri(final String redisKey, final String appName, final String key, final String field, final Class<T> clazz) {
        return new RedisExecutor<T>() {
            @Override
            public T execute(String redisClusterType, Object jedis, String appName) {
                try {
                	if(redisClusterType.equals("cluster")){
    	            	return SerializationInnerUtil.decode(((JedisCluster)jedis).hget((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET)), clazz);
                	}else{
                		return SerializationInnerUtil.decode(((Jedis)jedis).hget((appName + key).getBytes(Constant.CHARSET), field.getBytes(Constant.CHARSET)), clazz);
                	}
				} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
            }
        }.getResult(redisKey, appName);
    }
    public static byte[] hashGet(final String redisKey, final String appName, final String key, final byte[] field) {
    	return new RedisExecutor<byte[]>() {
    		@Override
    		public byte[] execute(String redisClusterType, Object jedis, String appName) {
    			try {
    				if(redisClusterType.equals("cluster")){
    					return ((JedisCluster)jedis).hget((appName + key).getBytes(Constant.CHARSET), field);
    				}else{
    					return ((Jedis)jedis).hget((appName + key).getBytes(Constant.CHARSET), field);
    				}
    			} catch (UnsupportedEncodingException e) {
    				logger.error(LogConstant.REDIS_CACHE, e);
    				return null;
    			}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表key中给定域 field的值. 如果哈希表key存在,同时设置这个key的有效期
     *
     * @param key key
     * @param field 域
     * @param expire 有效期（秒）
     * @return 给定域的值.当给定域不存在或是给定key不存在时,返回 nil.
     */
    public static String hashGet(final String redisKey, final String appName, final String key, final String field, final int expire) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	String result = ((Jedis)jedis).hget(appName + key, field);
                expire(redisKey, appName, key, expire);
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> T hashGet(final String redisKey, final String appName, final String key, final String field, final int expire, final Class<T> clazz) {
    	return new RedisExecutor<T>() {
    		@Override
    		public T execute(String redisClusterType, Object jedis, String appName) {
    			T result = null;
    			try {
					result = JsonInnerUtil.jsonToObject(((Jedis)jedis).hget(appName + key, field), clazz);
				} catch (JsonDeserializationException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
				}
    			expire(redisKey, appName, key, expire);
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 删除哈希表key中给定域 fields.<br>
     * 时间复杂度:O(1)
     *
     * @param key key
     * @param fields 域
     */
    public static Long hashDel(final String redisKey, final String appName, final String key, final String... fields) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).hdel(appName + key, fields);
            }
        }.getResult(redisKey, appName);
    }
    public static Long hashDel(final String redisKey, final String appName, final String key, final byte[] fields) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			try {
    				if(redisClusterType.equals("cluster")){
    	            	return ((JedisCluster)jedis).hdel((appName + key).getBytes(Constant.CHARSET), fields);
                	}else{
                		return ((Jedis)jedis).hdel((appName + key).getBytes(Constant.CHARSET), fields);
                	}
				} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    		}
    	}.getResult(redisKey, appName);
    }

    public static Long hincrBy(final String redisKey, final String appName, final String key, final String field, final Long value) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
				if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).hincrBy(appName + key, field, value);
            	}else{
            		return ((Jedis)jedis).hincrBy(appName + key, field, value);
            	}
    		}
    	}.getResult(redisKey, appName);
    }
    /**
     * 同时将多个 field-value (域-值)对设置到哈希表key中. <br>
     * 时间复杂度: O(N) (N为fields的数量)
     *
     * @param key key
     * @param hash field-value的map
     * @return 如果命令执行成功,返回 OK .当 key不是哈希表(hash)类型时,返回一个错误.
     */
    public static String hashMultipleSet(final String redisKey, final String appName, final String key, final Map<String, String> hash) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(hash == null || hash.size() == 0){
            		return "";
            	}
            	if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).hmset(appName + key, hash);
            	}else{
            		return ((Jedis)jedis).hmset(appName + key, hash);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> String hashMultipleSetT(final String redisKey, final String appName, final String key, final Map<String, T> hash) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			if(hash == null || hash.size() == 0){
            		return "";
            	}
    			Map<String, String> hashs = new HashMap<String, String>(hash.size());
    			Iterator<Entry<String, T>> it = hash.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<String, T> entry = it.next();
    				hashs.put(entry.getKey(), JsonInnerUtil.objecttoJSon(entry.getValue()));
    			}
    			if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).hmset(appName + key, hashs);
            	}else{
            		return ((Jedis)jedis).hmset(appName + key, hashs);
            	}
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 同时将多个 field-value (域-值)对设置到哈希表 key 中.同时设置这个key的生存时间
     *
     * @param key key
     * @param hash field-value的map
     * @param expire 生命周期,单位为秒
     * @return 如果命令执行成功,返回 OK .当 key 不是哈希表(hash)类型时,返回一个错误.
     */
    public static String hashMultipleSet(final String redisKey, final String appName, final String key, final Map<String, String> hash, final int expire) {
        return new RedisExecutor<String>() {
            @Override
            public String execute(String redisClusterType, Object jedis, String appName) {
            	if(hash == null || hash.size() == 0){
            		return "";
            	}
                String result = ((Jedis)jedis).hmset(appName + key, hash);
                expire(redisKey, appName, key, expire);
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> String hashMultipleSetT(final String redisKey, final String appName, final String key, final Map<String, T> hash, final int expire) {
    	return new RedisExecutor<String>() {
    		@Override
    		public String execute(String redisClusterType, Object jedis, String appName) {
    			if(hash == null || hash.size() == 0){
            		return "";
            	}
    			Map<String, String> hashs = new HashMap<String, String>(hash.size());
    			Iterator<Entry<String, T>> it = hash.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<String, T> entry = it.next();
    				hashs.put(entry.getKey(), JsonInnerUtil.objecttoJSon(entry.getValue()));
    			}
    			String result = ((Jedis)jedis).hmset(appName + key, hashs);
    			expire(redisKey, appName, key, expire);
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表 key中,一个或多个给定域的值.如果给定的域不存在于哈希表,那么返回一个 nil值.<br>
     * 时间复杂度: O(N) (N为fields的数量)
     *
     * @param key key
     * @param fields field的数组
     * @return 一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样.
     */
    public static List<String> hashMultipleGet(final String redisKey, final String appName, final String key, final String... fields) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(fields == null || fields.length == 0){
            		return new ArrayList<String>(0);
            	}
                return ((Jedis)jedis).hmget(appName + key, fields);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<T> hashMultipleGet(final String redisKey, final String appName, final String key, final Class<T> clazz, final String... fields) {
    	return new RedisExecutor<List<T>>() {
    		@Override
    		public List<T> execute(String redisClusterType, Object jedis, String appName) {
    			if(fields == null || fields.length == 0){
            		return new ArrayList<T>(0);
            	}
    			List<String> result = ((Jedis)jedis).hmget(appName + key, fields);
    			if(result == null || result.size() == 0){
    				return new ArrayList<T>(0);
    			}
    			List<T> resultT = new ArrayList<T>(result.size());
    			for (String value : result) {
    				try {
						resultT.add(JsonInnerUtil.jsonToObject(value, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
				}
    			return resultT;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表 key中,一个或多个给定域的值.如果给定的域不存在于哈希表,那么返回一个 nil值. 同时设置这个 key的生存时间
     *
     * @param key key
     * @param fields field的数组
     * @param expire 生命周期,单位为秒
     * @return 一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样.
     */
    public static List<String> hashMultipleGet(final String redisKey, final String appName, final String key, final int expire, final String... fields) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(fields == null || fields.length == 0){
            		return new ArrayList<String>(0);
            	}
                List<String> result = ((Jedis)jedis).hmget(appName + key, fields);
                expire(redisKey, appName, key, expire);
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<T> hashMultipleGet(final String redisKey, final String appName, final String key, final int expire, final Class<T> clazz, final String... fields) {
    	return new RedisExecutor<List<T>>() {
    		@Override
    		public List<T> execute(String redisClusterType, Object jedis, String appName) {
    			if(fields == null || fields.length == 0){
            		return new ArrayList<T>(0);
            	}
    			List<String> result = ((Jedis)jedis).hmget(appName + key, fields);
    			if(result == null || result.size() == 0){
    				return new ArrayList<T>(0);
    			}
    			List<T> resultT = new ArrayList<T>(result.size());
    			for (String value : result) {
    				try {
						resultT.add(JsonInnerUtil.jsonToObject(value, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
				}
    			expire(redisKey, appName, key, expire);
    			return resultT;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量{@link #hashMultipleSet(String, Map)}
     *
     * @param pairs 多个hash的多个field
     * @return 操作状态的集合
     */
    public static List<String> batchHashMultiSet(final String redisKey, final String appName, final List<Pair<String, Map<String, String>>> pairs) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(pairs == null || pairs.size() == 0){
            		return new ArrayList<String>(0);
            	}
            	List<String> result = new ArrayList<String>(pairs.size());
                for (Pair<String, Map<String, String>> pair : pairs) {
                	result.add(((Jedis)jedis).hmset(appName + pair.getKey(), pair.getValue()));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<String> batchHashMultiSetT(final String redisKey, final String appName, final List<Pair<String, Map<String, T>>> pairs) {
    	return new RedisExecutor<List<String>>() {
    		@Override
    		public List<String> execute(String redisClusterType, Object jedis, String appName) {
    			if(pairs == null || pairs.size() == 0){
            		return new ArrayList<String>(0);
            	}
    			List<String> result = new ArrayList<String>(pairs.size());
    			for (Pair<String, Map<String, T>> pair : pairs) {
    				Map<String, String> hashs = new HashMap<String, String>();
        			Iterator<Entry<String, T>> it = pair.getValue().entrySet().iterator();
        			while(it.hasNext()){
        				Entry<String, T> entry = it.next();
        				hashs.put(entry.getKey(), JsonInnerUtil.objecttoJSon(entry.getValue()));
        			}
    				result.add(((Jedis)jedis).hmset(appName + pair.getKey(), hashs));
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量{@link #hashMultipleSet(String, Map)}
     *
     * @param data Map<String, Map<String, String>>格式的数据
     * @return 操作状态的集合
     */
    public static List<String> batchHashMultiSet(final String redisKey, final String appName, final Map<String, Map<String, String>> data) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(data == null || data.size() == 0){
            		return new ArrayList<String>(0);
            	}
            	List<String> result = new ArrayList<String>();
                for (Entry<String, Map<String, String>> iter : data.entrySet()) {
                	result.add(((Jedis)jedis).hmset(appName + iter.getKey(), iter.getValue()));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<String> batchHashMultiSetT(final String redisKey, final String appName, final Map<String, Map<String, T>> data) {
    	return new RedisExecutor<List<String>>() {
    		@Override
    		public List<String> execute(String redisClusterType, Object jedis, String appName) {
    			if(data == null || data.size() == 0){
            		return new ArrayList<String>(0);
            	}
    			List<String> result = new ArrayList<String>(data.size());
    			for (Entry<String, Map<String, T>> iter : data.entrySet()) {
    				Map<String, String> hashs = new HashMap<String, String>();
        			Iterator<Entry<String, T>> it = iter.getValue().entrySet().iterator();
        			while(it.hasNext()){
        				Entry<String, T> entry = it.next();
        				hashs.put(entry.getKey(), JsonInnerUtil.objecttoJSon(entry.getValue()));
        			}
    				result.add(((Jedis)jedis).hmset(appName + iter.getKey(), hashs));
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量{@link #hashMultipleGet(String, String...)}
     *
     * @param pairs 多个hash的多个field
     * @return 执行结果的集合
     */
    public static List<List<String>> batchHashMultiGet(final String redisKey, final String appName, final List<Pair<String, String[]>> pairs) {
        return new RedisExecutor<List<List<String>>>() {
            @Override
            public List<List<String>> execute(String redisClusterType, Object jedis, String appName) {
            	if(pairs == null || pairs.size() == 0){
            		return new ArrayList<List<String>>(0);
            	}
            	List<List<String>> result = new ArrayList<List<String>>(pairs.size());
                for (Pair<String, String[]> pair : pairs) {
                	result.add(((Jedis)jedis).hmget(appName + pair.getKey(), pair.getValue()));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<List<T>> batchHashMultiGet(final String redisKey, final String appName, final List<Pair<String, String[]>> pairs, final Class<T> clazz) {
    	return new RedisExecutor<List<List<T>>>() {
    		@Override
    		public List<List<T>> execute(String redisClusterType, Object jedis, String appName) {
    			if(pairs == null || pairs.size() == 0){
            		return new ArrayList<List<T>>(0);
            	}
    			List<List<T>> resultT = new ArrayList<List<T>>(pairs.size());
    			for (Pair<String, String[]> pair : pairs) {
    				List<String> result = ((Jedis)jedis).hmget(appName + pair.getKey(), pair.getValue());
    				if(result != null && result.size() > 0){
    					List<T> tmp = new ArrayList<T>();
    					for (String value : result) {
    						try {
								tmp.add(JsonInnerUtil.jsonToObject(value, clazz));
							} catch (JsonDeserializationException e) {
								logger.error(LogConstant.REDIS_CACHE, e);
							}
						}
    					resultT.add(tmp);
    				}
    			}
    			return resultT;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表 key中,所有的域和值.<br>
     * 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍. <br>
     * 时间复杂度: O(N)
     *
     * @param key key
     * @return 以列表形式返回哈希表的域和域的值.若 key不存在,返回空列表.
     */
    public static Map<String, String> hashGetAll(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Map<String, String>>() {
            @Override
            public Map<String, String> execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
	            	return ((JedisCluster)jedis).hgetAll(appName + key);
            	}else{
            		return ((Jedis)jedis).hgetAll(appName + key);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Map<String, T> hashGetAll(final String redisKey, final String appName, final String key, final Class<T> clazz) {
    	return new RedisExecutor<Map<String, T>>() {
    		@Override
    		public Map<String, T> execute(String redisClusterType, Object jedis, String appName) {
    			Map<String, String> map = null;
    			if(redisClusterType.equals("cluster")){
    				map = ((JedisCluster)jedis).hgetAll(appName + key);
    			}else{
    				map = ((Jedis)jedis).hgetAll(appName + key);
    			}
    			if(map == null || map.size() == 0){
    				return new HashMap<String, T>(0);
    			}
    			Map<String, T> result = new HashMap<String, T>(map.size());
    			Iterator<Entry<String, String>> it = map.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<String, String> entry = it.next();
    				try {
						result.put(entry.getKey(), JsonInnerUtil.jsonToObject(entry.getValue(), clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static <T extends Serializable> Map<String, T> hashGetAllImplSeri(final String redisKey, final String appName, final String key, final Class<T> clazz) {
    	return new RedisExecutor<Map<String, T>>() {
    		@Override
    		public Map<String, T> execute(String redisClusterType, Object jedis, String appName) {
    			Map<byte[], byte[]> map = null;
    			try {
    				if(redisClusterType.equals("cluster")){
    					map = ((JedisCluster)jedis).hgetAll((appName + key).getBytes(Constant.CHARSET));
    				}else{
    					map = ((Jedis)jedis).hgetAll((appName + key).getBytes(Constant.CHARSET));
    				}
				} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
    			if(map == null || map.size() == 0){
    				return new HashMap<String, T>(0);
    			}
    			Map<String, T> result = new HashMap<String, T>(map.size());
    			Iterator<Entry<byte[], byte[]>> it = map.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<byte[], byte[]> entry = it.next();
    				try {
    					result.put(new String(entry.getKey(), Constant.CHARSET), SerializationInnerUtil.decode(entry.getValue(), clazz));
    				} catch (Exception e) {
    					logger.error(LogConstant.REDIS_CACHE, e);
    				}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static Map<byte[], byte[]> hashGetAllByteArr(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<Map<byte[], byte[]>>() {
            @Override
            public Map<byte[], byte[]> execute(String redisClusterType, Object jedis, String appName) {
                try {
                	if(redisClusterType.equals("cluster")){
    	            	return ((JedisCluster)jedis).hgetAll((appName + key).getBytes(Constant.CHARSET));
                	}else{
                		return ((Jedis)jedis).hgetAll((appName + key).getBytes(Constant.CHARSET));
                	}
				} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 返回哈希表 key中,所有的域和值,同时设置这个 key 的生存时间.<br>
     * 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍.
     *
     * @param key key
     * @param expire 生命周期,单位为秒
     * @return 以列表形式返回哈希表的域和域的值.若 key 不存在,返回空列表.
     */
    public static Map<String, String> hashGetAll(final String redisKey, final String appName, final String key, final int expire) {
        return new RedisExecutor<Map<String, String>>() {
            @Override
            public Map<String, String> execute(String redisClusterType, Object jedis, String appName) {
                Map<String, String> result = ((Jedis)jedis).hgetAll(appName + key);
                expire(redisKey, appName, key, expire);
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Map<String, T> hashGetAll(final String redisKey, final String appName, final String key, final int expire, final Class<T> clazz) {
    	return new RedisExecutor<Map<String, T>>() {
    		@Override
    		public Map<String, T> execute(String redisClusterType, Object jedis, String appName) {
    			Map<String, String> map = ((Jedis)jedis).hgetAll(appName + key);
    			if(map == null || map.size() == 0){
    				return new HashMap<String, T>(0);
    			}
    			Map<String, T> result = new HashMap<String, T>(map.size());
    			Iterator<Entry<String, String>> it = map.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<String, String> entry = it.next();
    				try {
						result.put(entry.getKey(), JsonInnerUtil.jsonToObject(entry.getValue(), clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			expire(redisKey, appName, key, expire);
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量{@link #hashGetAll(String)}
     *
     * @param keys key的数组
     * @return 执行结果的集合
     */
    public static List<Map<String, String>> batchHashGetAll(final String redisKey, final String appName, final String... keys) {
        return new RedisExecutor<List<Map<String, String>>>() {
            @Override
            public List<Map<String, String>> execute(String redisClusterType, Object jedis, String appName) {
            	if(keys == null || keys.length == 0){
            		return new ArrayList<Map<String, String>>(0);
            	}
                List<Map<String, String>> result = new ArrayList<Map<String, String>>(keys.length);
                for (String key : keys) {
                	result.add(((Jedis)jedis).hgetAll(appName + key));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<Map<String, T>> batchHashGetAll(final String redisKey, final String appName, final Class<T> clazz, final String... keys) {
    	return new RedisExecutor<List<Map<String, T>>>() {
    		@Override
    		public List<Map<String, T>> execute(String redisClusterType, Object jedis, String appName) {
    			if(keys == null || keys.length == 0){
            		return new ArrayList<Map<String, T>>(0);
            	}
    			List<Map<String, T>> resultT = new ArrayList<Map<String, T>>(keys.length);
    			for (String key : keys) {
    				Map<String, String> map = ((Jedis)jedis).hgetAll(appName + key);
    				if(map != null && map.size() > 0){
    					Map<String, T> mapt = new HashMap<String, T>();
    					Iterator<Entry<String, String>> it = map.entrySet().iterator();
    	    			while(it.hasNext()){
    	    				Entry<String, String> entry = it.next();
    	    				try {
								mapt.put(entry.getKey(), JsonInnerUtil.jsonToObject(entry.getValue(), clazz));
							} catch (JsonDeserializationException e) {
								logger.error(LogConstant.REDIS_CACHE, e);
							}
    	    			}
    					resultT.add(mapt);
    				}
    			}

    			return resultT;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 批量{@link #hashMultipleGet(String, String...)},与{@link #batchHashGetAll(String...)}
     * 不同的是,返回值为Map类型
     *
     * @param keys key的数组
     * @return 多个hash的所有filed和value
     */
    public static Map<String, Map<String, String>> batchHashGetAllForMap(final String redisKey, final String appName, final String... keys) {
        return new RedisExecutor<Map<String, Map<String, String>>>() {
            @Override
            public Map<String, Map<String, String>> execute(String redisClusterType, Object jedis, String appName) {
            	if(keys == null || keys.length == 0){
            		return new HashMap<String, Map<String, String>>(0);
            	}
                // 设置map容量防止rehash
                int capacity = 1;
                while ((int) (capacity * 0.75) <= keys.length) {
                    capacity <<= 1;
                }
                Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>(capacity);
                for (String key : keys) {
                	result.put(key, ((Jedis)jedis).hgetAll(appName + key));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Map<String, Map<String, T>> batchHashGetAllForMap(final String redisKey, final String appName, final Class<T> clazz, final String... keys) {
    	return new RedisExecutor<Map<String, Map<String, T>>>() {
    		@Override
    		public Map<String, Map<String, T>> execute(String redisClusterType, Object jedis, String appName) {
    			if(keys == null || keys.length == 0){
            		return new HashMap<String, Map<String, T>>(0);
            	}
    			// 设置map容量防止rehash
    			int capacity = 1;
    			while ((int) (capacity * 0.75) <= keys.length) {
    				capacity <<= 1;
    			}
    			Map<String, Map<String, T>> resultT = new HashMap<String, Map<String, T>>(capacity);
    			for (String key : keys) {
    				Map<String, String> map = ((Jedis)jedis).hgetAll(appName + key);
    				if(map != null && map.size() > 0){
    					Map<String, T> mapt = new HashMap<String, T>();
    					Iterator<Entry<String, String>> it = map.entrySet().iterator();
    	    			while(it.hasNext()){
    	    				Entry<String, String> entry = it.next();
    	    				try {
								mapt.put(entry.getKey(), JsonInnerUtil.jsonToObject(entry.getValue(), clazz));
							} catch (JsonDeserializationException e) {
								logger.error(LogConstant.REDIS_CACHE, e);
							}
    	    			}
    					resultT.put(key, mapt);
    				}
    			}
    			return resultT;
    		}
    	}.getResult(redisKey, appName);
    }

    /* ================================List================================ */

    /**
     * 将一个或多个值value插入到列表 key的表尾(最右边).<br>
     * RPUSH mylist a b c 会返回一个列表，其第一个元素是 a ，第二个元素是 b ，第三个元素是 c
     *
     * @param key key
     * @param values value的数组
     * @return 执行listPushTail操作后,表的长度
     */
    public static Long listPushTail(final String redisKey, final String appName, final String key, final String... values) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(values == null || values.length == 0){
            		return 0l;
            	}
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).rpush(appName + key, values);
            	}else {
            		return ((Jedis)jedis).rpush(appName + key, values);
            	}
            }
        }.getResult(redisKey, appName);
    }
	public static Long listPushTail(final String redisKey, final String appName, final String key, final Object... values) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			if(values == null || values.length == 0){
            		return 0l;
            	}
    			String[] arr = new String[values.length];
    			for (int i = 0; i < values.length; i++) {
    				arr[i] = JsonInnerUtil.objecttoJSon(values[i]);
				}
    			if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).rpush(appName + key, arr);
            	}else {
            		return ((Jedis)jedis).rpush(appName + key, arr);
            	}
    		}
    	}.getResult(redisKey, appName);
    }
	@SuppressWarnings("unchecked")
	public static <T extends Serializable> Long listPushTailImplSeri(final String redisKey, final String appName, final String key, final T... values) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(values == null || values.length == 0){
            		return 0l;
            	}
            	byte[][] byteValues = new byte[values.length][];
            	int i=0;
            	for (T value : values) {
            		byteValues[i++] = SerializationInnerUtil.encode(value);
				}
            	try {
	            	if(redisClusterType.equals("cluster")){
	            		return ((JedisCluster)jedis).rpush((appName + key).getBytes(Constant.CHARSET), byteValues);
	            	}else{
	            		return ((Jedis)jedis).rpush((appName + key).getBytes(Constant.CHARSET), byteValues);
	            	}
            	} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 将一个或多个值 value插入到列表 key的表头(最左边).<br>
     * LPUSH mylist a b c，返回的列表是 c 为第一个元素， b 为第二个元素， a 为第三个元素
     *
     * @param key key
     * @param values values
     * @return 执行 listPushHead 命令后,列表的长度.
     */
    public static Long listPushHead(final String redisKey, final String appName, final String key, final String... values) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(values == null || values.length == 0){
            		return 0l;
            	}
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).lpush(appName + key, values);
            	}else {
            		return ((Jedis)jedis).lpush(appName + key, values);
            	}
            }
        }.getResult(redisKey, appName);
    }
	public static Long listPushHead(final String redisKey, final String appName, final String key, final Object... values) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			if(values == null || values.length == 0){
            		return 0l;
            	}
    			String[] arr = new String[values.length];
    			for (int i = 0; i < values.length; i++) {
    				arr[i] = JsonInnerUtil.objecttoJSon(values[i]);
				}
    			if(redisClusterType.equals("cluster")){
            		return ((Jedis)jedis).lpush(appName + key, arr);
            	}else {
            		return ((Jedis)jedis).lpush(appName + key, arr);
            	}
    		}
    	}.getResult(redisKey, appName);
    }
	@SuppressWarnings("unchecked")
	public static <T extends Serializable> Long listPushHeadImplSeri(final String redisKey, final String appName, final String key, final T... values) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(values == null || values.length == 0){
            		return 0l;
            	}
            	byte[][] byteValues = new byte[values.length][];
            	int i=0;
            	for (T value : values) {
            		byteValues[i++] = SerializationInnerUtil.encode(value);
				}
            	try {
	            	if(redisClusterType.equals("cluster")){
	            		return ((JedisCluster)jedis).lpush((appName + key).getBytes(Constant.CHARSET), byteValues);
	            	}else{
	            		return ((Jedis)jedis).lpush((appName + key).getBytes(Constant.CHARSET), byteValues);
	            	}
            	} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
            }
        }.getResult(redisKey, appName);
    }

    /**
     * 将一个或多个值 value 插入到列表 key 的表头, 当列表大于指定长度是就对列表进行修剪(trim)
     *
     * @param key key
     * @param values values
     * @param size 链表超过这个长度就修剪元素
     * @return 执行 listPushHeadAndTrim 命令后,列表的长度.
     */
    public static Long listPushHeadAndTrim(final String redisKey, final String appName, final String key, final long size, final String... values) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(values == null || values.length == 0){
            		return 0l;
            	}
                Long result = ((Jedis)jedis).lpush(appName + key, values);
                // 修剪列表元素, 如果 size - 1 比 end 下标还要大,Redis将 size 的值设置为 end .
                ((Jedis)jedis).ltrim(appName + key, 0, size - 1);
                return result;
            }
        }.getResult(redisKey, appName);
    }
	public static Long listPushHeadAndTrim(final String redisKey, final String appName, final String key, final long size, final Object... values) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			if(values == null || values.length == 0){
            		return 0l;
            	}
    			String[] arr = new String[values.length];
    			for (int i = 0; i < values.length; i++) {
    				arr[i] = JsonInnerUtil.objecttoJSon(values[i]);
				}
    			Long result = ((Jedis)jedis).lpush(appName + key, arr);
    			// 修剪列表元素, 如果 size - 1 比 end 下标还要大,Redis将 size 的值设置为 end .
    			((Jedis)jedis).ltrim(appName + key, 0, size - 1);
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

	public static String listPop(final String redisKey, final String appName, final String key) {
		return new RedisExecutor<String>() {
			@Override
			public String execute(String redisClusterType, Object jedis, String appName) {
				if(redisClusterType.equals("cluster")){
    				return ((JedisCluster)jedis).lpop(appName+key);
    			}else{
    				return ((Jedis)jedis).lpop(appName+key);
    			}
			}
		}.getResult(redisKey, appName);
	}
	public static <T extends Serializable> T listPopImplSeri(final String redisKey, final String appName, final String key, Class<T> clazz) {
		return new RedisExecutor<T>() {
			@Override
			public T execute(String redisClusterType, Object jedis, String appName) {
				try {
					if(redisClusterType.equals("cluster")){
						return SerializationInnerUtil.decode(((JedisCluster)jedis).lpop((appName + key).getBytes(Constant.CHARSET)), clazz);
	    			}else{
	    				return SerializationInnerUtil.decode(((Jedis)jedis).lpop((appName + key).getBytes(Constant.CHARSET)), clazz);
	    			}
				} catch (UnsupportedEncodingException e) {
					logger.error(LogConstant.REDIS_CACHE, e);
					return null;
				}
			}
		}.getResult(redisKey, appName);
	}

    /**
     * 返回list所有元素,下标从0开始,负值表示从后面计算,-1表示倒数第一个元素,key不存在返回空列表
     *
     * @param key key
     * @return list所有元素
     */
    public static List<String> listGetAll(final String redisKey, final String appName, final String key) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).lrange(appName + key, 0, -1);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<T> listGetAll(final String redisKey, final String appName, final String key, final Class<T> clazz) {
    	return new RedisExecutor<List<T>>() {
    		@Override
    		public List<T> execute(String redisClusterType, Object jedis, String appName) {
    			List<String> l = ((Jedis)jedis).lrange(appName + key, 0, -1);
    			if(l == null || l.size() == 0){
    				return new ArrayList<T>(0);
    			}
    			List<T> result = new ArrayList<T>(l.size());
    			for (String value : l) {
    				try {
						result.add(JsonInnerUtil.jsonToObject(value, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
				}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回指定区间内的元素,下标从0开始,负值表示从后面计算,-1表示倒数第一个元素,key不存在返回空列表
     *
     * @param key key
     * @param beginIndex 下标开始索引（包含）
     * @param endIndex 下标结束索引（不包含）
     * @return 指定区间内的元素
     */
    public static List<String> listRange(final String redisKey, final String appName, final String key, final long beginIndex, final long endIndex) {
        return new RedisExecutor<List<String>>() {
            @Override
            public List<String> execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).lrange(appName + key, beginIndex, endIndex - 1);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> List<T> listRange(final String redisKey, final String appName, final String key, final long beginIndex, final long endIndex, final Class<T> clazz) {
    	return new RedisExecutor<List<T>>() {
    		@Override
    		public List<T> execute(String redisClusterType, Object jedis, String appName) {
    			List<String> l = ((Jedis)jedis).lrange(appName + key, beginIndex, endIndex - 1);
    			if(l == null || l.size() == 0){
    				return new ArrayList<T>(0);
    			}
    			List<T> result = new ArrayList<T>(l.size());
    			for (String value : l) {
    				try {
						result.add(JsonInnerUtil.jsonToObject(value, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
				}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 一次获得多个链表的数据
     *
     * @param keys key的数组
     * @return 执行结果
     */
    public static Map<String, List<String>> batchGetAllList(final String redisKey, final String appName, final String[] keys) {
        return new RedisExecutor<Map<String, List<String>>>() {
            @Override
            public Map<String, List<String>> execute(String redisClusterType, Object jedis, String appName) {
            	if(keys == null || keys.length == 0){
            		return new HashMap<String, List<String>>(0);
            	}
                Map<String, List<String>> result = new HashMap<String, List<String>>(keys.length);
                for (String key : keys) {
                	result.put(key, ((Jedis)jedis).lrange(appName + key, 0, -1));
                }
                return result;
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Map<String, List<T>> batchGetAllList(final String redisKey, final String appName, final String[] keys, final Class<T> clazz) {
    	return new RedisExecutor<Map<String, List<T>>>() {
    		@Override
    		public Map<String, List<T>> execute(String redisClusterType, Object jedis, String appName) {
    			if(keys == null || keys.length == 0){
            		return new HashMap<String, List<T>>(0);
            	}
    			Map<String, List<T>> result = new HashMap<String, List<T>>(keys.length);
    			for (String key : keys) {
    				List<String> l = ((Jedis)jedis).lrange(appName + key, 0, -1);
    				if(l != null && l.size() > 0){
    					List<T> vs = new ArrayList<T>(l.size());
    					for (String value : l) {
    						try {
								vs.add(JsonInnerUtil.jsonToObject(value, clazz));
							} catch (JsonDeserializationException e) {
								logger.error(LogConstant.REDIS_CACHE, e);
							}
						}
    					result.put(key, vs);
    				}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    /* ======================================Sorted set================================= */

    /**
     * 将一个 member 元素及其 score 值加入到有序集 key 当中.
     *
     * @param key key
     * @param score score 值可以是整数值或双精度浮点数.
     * @param member 有序集的成员
     * @return 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员.
     */
    public static Long addWithSortedSet(final String redisKey, final String appName, final String key, final double score, final String member) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).zadd(appName + key, score, member);
            	}else{
            		return ((Jedis)jedis).zadd(appName + key, score, member);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Long addWithSortedSet(final String redisKey, final String appName, final String key, final double score, final T member) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			return ((Jedis)jedis).zadd(appName + key, score, JsonInnerUtil.objecttoJSon(member));
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 将多个 member 元素及其 score 值加入到有序集 key 当中.
     *
     * @param key key
     * @param scoreMembers score、member的pair
     * @return 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员.
     */
    public static Long addWithSortedSet(final String redisKey, final String appName, final String key, final Map<String, Double> scoreMembers) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(scoreMembers == null || scoreMembers.size() == 0){
    				return 0l;
    			}
                return ((Jedis)jedis).zadd(appName + key, scoreMembers);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Long addWithSortedSetT(final String redisKey, final String appName, final String key, final Map<T, Double> scoreMembersT) {
    	return new RedisExecutor<Long>() {
    		@Override
    		public Long execute(String redisClusterType, Object jedis, String appName) {
    			if(scoreMembersT == null || scoreMembersT.size() == 0){
    				return 0l;
    			}
    			Map<String, Double> scoreMembers = new HashMap<String, Double>(scoreMembersT.size());
    			Iterator<Entry<T, Double>> it = scoreMembersT.entrySet().iterator();
    			while(it.hasNext()){
    				Entry<T, Double> entry = it.next();
    				scoreMembers.put(JsonInnerUtil.objecttoJSon(entry.getKey()), entry.getValue());
    			}
    			return ((Jedis)jedis).zadd(appName + key, scoreMembers);
    		}
    	}.getResult(redisKey, appName);
    }

    /**
     * 返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员. 有序集成员按 score 值递减(从大到小)的次序排列.
     *
     * @param key key
     * @param max score最大值
     * @param min score最小值
     * @return 指定区间内,带有 score 值(可选)的有序集成员的列表
     */
    public static Set<String> revrangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min) {
        return new RedisExecutor<Set<String>>() {
            @Override
            public Set<String> execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).zrevrangeByScore(appName + key, max, min);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Set<T> revrangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final Class<T> clazz) {
    	return new RedisExecutor<Set<T>>() {
    		@Override
    		public Set<T> execute(String redisClusterType, Object jedis, String appName) {
    			Set<String> set = ((Jedis)jedis).zrevrangeByScore(appName + key, max, min);
    			if(set == null || set.size() == 0){
    				return new HashSet<T>(0);
    			}
    			Set<T> result = new HashSet<T>(set.size());
    			Iterator<String> it = set.iterator();
    			while(it.hasNext()){
    				String v = it.next();
    				try {
						result.add(JsonInnerUtil.jsonToObject(v, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static Set<String> revrangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final int offset, final int count) {
        return new RedisExecutor<Set<String>>() {
            @Override
            public Set<String> execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).zrevrangeByScore(appName + key, max, min, offset, count);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Set<T> revrangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final int offset, final int count, final Class<T> clazz) {
    	return new RedisExecutor<Set<T>>() {
    		@Override
    		public Set<T> execute(String redisClusterType, Object jedis, String appName) {
    			Set<String> set = ((Jedis)jedis).zrevrangeByScore(appName + key, max, min, offset, count);
    			if(set == null || set.size() == 0){
    				return new HashSet<T>(0);
    			}
    			Set<T> result = new HashSet<T>(set.size());
    			Iterator<String> it = set.iterator();
    			while(it.hasNext()){
    				String v = it.next();
    				try {
						result.add(JsonInnerUtil.jsonToObject(v, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    public static Set<String> rangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min) {
        return new RedisExecutor<Set<String>>() {
            @Override
            public Set<String> execute(String redisClusterType, Object jedis, String appName) {
                return ((Jedis)jedis).zrangeByScore(appName + key, min, max);
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Set<T> rangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final Class<T> clazz) {
    	return new RedisExecutor<Set<T>>() {
    		@Override
    		public Set<T> execute(String redisClusterType, Object jedis, String appName) {
    			Set<String> set = ((Jedis)jedis).zrangeByScore(appName + key, min, max);
    			if(set == null || set.size() == 0){
    				return new HashSet<T>(0);
    			}
    			Set<T> result = new HashSet<T>(set.size());
    			Iterator<String> it = set.iterator();
    			while(it.hasNext()){
    				String v = it.next();
    				try {
						result.add(JsonInnerUtil.jsonToObject(v, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }
    public static Set<String> rangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final int offset, final int count) {
        return new RedisExecutor<Set<String>>() {
            @Override
            public Set<String> execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).zrangeByScore(appName + key, min, max, offset, count);
            	}else{
            		return ((Jedis)jedis).zrangeByScore(appName + key, min, max, offset, count);
            	}
            }
        }.getResult(redisKey, appName);
    }
    public static <T> Set<T> rangeByScoreWithSortedSet(final String redisKey, final String appName, final String key, final double max, final double min, final int offset, final int count, final Class<T> clazz) {
    	return new RedisExecutor<Set<T>>() {
    		@Override
    		public Set<T> execute(String redisClusterType, Object jedis, String appName) {
    			Set<String> set = ((Jedis)jedis).zrangeByScore(appName + key, min, max, offset, count);
    			if(set == null || set.size() == 0){
    				return new HashSet<T>(0);
    			}
    			Set<T> result = new HashSet<T>(set.size());
    			Iterator<String> it = set.iterator();
    			while(it.hasNext()){
    				String v = it.next();
    				try {
						result.add(JsonInnerUtil.jsonToObject(v, clazz));
					} catch (JsonDeserializationException e) {
						logger.error(LogConstant.REDIS_CACHE, e);
					}
    			}
    			return result;
    		}
    	}.getResult(redisKey, appName);
    }

    public static Long zrem(final String redisKey, final String appName, final String key, final String... member) {
        return new RedisExecutor<Long>() {
            @Override
            public Long execute(String redisClusterType, Object jedis, String appName) {
            	if(redisClusterType.equals("cluster")){
            		return ((JedisCluster)jedis).zrem(appName + key, member);
            	}else{
            		return ((Jedis)jedis).zrem(appName + key, member);
            	}
            }
        }.getResult(redisKey, appName);
    }

}